home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Disc to the Future 2
/
Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin
/
MAC
/
THINKC
/
TCL1
/
CTRACE2_
/
CTRACE.C
< prev
next >
Wrap
Text File
|
1990-12-10
|
7KB
|
214 lines
/*****
CTRACE: A MESSAGE LOGGING CLASS
by William D. Cramer in Dr. Dobbs Journal #170, p. 44-55, 116-120.
*****/
/** CTrace.c -- Methods for the trace document class. **/
#include "CTrace.h" /* trace class parameters */
/** Global declaration **/
CTrace *gTrace; /* the one instance of this class */
/** ITrace() -- Initializes trace document object. **/
void CTrace::ITrace
(
short records /* number of records before wrap */
)
{
Rect frameRect; /* window frame */
CDocument::IDocument (gApplication, TRUE);
itsWindow = new (CWindow);
itsWindow->IWindow (TRACE_WINDOW_ID, FALSE, gDesktop, this);
itsWindow->GetFrame (&frameRect);
itsWindow->Move (gDesktop->bounds.right - frameRect.right - RIGHT_SMARGIN,gDesktop->bounds.top + TOP_SMARGIN);
itsLogPanorama = new (CLogPanorama);
itsLogPanorama->ILogPane (records, this, itsWindow);
itsMainPane = itsLogPanorama;
currMask = TRACE_DEFAULT_MASK;
gTrace = this;
}
/** ToggleTraceWindow() -- Toggles visibility of trace window. **/
void CTrace::ToggleTraceWindow(void)
{
if (itsWindow->visible)
itsWindow->Hide ();
else
{
itsWindow->Show ();
itsWindow->Select ();
}
}
/** Close() -- Overrides normal document method by closing trace window. **/
Boolean CTrace::Close
(
Boolean quitting /* ignored */
)
{
itsWindow->Hide ();
return (TRUE);
}
/** SetTraceMask -- Allows user to set/clear defined trace masks.**/
void CTrace::SetTraceMask (void)
{
int bitNum, /* bit number within the trace mask */
checkBoxState, /* state of a checkbox (0=unset,1=set) */
item, /* loop counter */
itemType, /* item type (4=button, 5=checkbox) */
whichItem; /* item number selected by user */
Handle itemStuff; /* handle to dialog item parameters */
Boolean done; /* loop-termination flag */
Str255 title; /* text associated with a dialog item */
Rect itemRect; /* rectangle surrounding a control */
DialogPtr maskDialog; /* structure for dialog box */
/* Pull up the mask dialog box out of the resource fork */
maskDialog = GetNewDialog (TRACE_MASK_DIALOG, NULL, (Ptr)(-1));
/* Run through checkboxes */
for (item=FIRST_MASK, bitNum=0;
item<=LAST_MASK; item++,
bitNum++)
{
GetDItem (maskDialog, item, &itemType, &itemStuff, &itemRect);
GetCTitle ( (ControlHandle)itemStuff, title);
PtoCstr ((char*)title);
if (strcmp((char*)title, "Undefined") != 0)
{
checkBoxState = ((currMask&(1L<<bitNum)) == 0L) ? 0 : 1;
SetCtlValue ( (ControlHandle) itemStuff, checkBoxState);
}
else
HiliteControl (itemStuff, UNHILITE_CONTROL);
}
/* The default button (#1) is the okay button, draw outline around it. */
GetDItem (maskDialog, OKAY_BUTTON_ITEM, &itemType, &itemStuff, &itemRect);
SetPort (maskDialog);
PenSize (3, 3);
InsetRect (&itemRect, -4, -4);
FrameRoundRect (&itemRect, 16, 16);
/* Get events from dialog manager and process accordingly */
done = FALSE;
while (!done)
{
ModalDialog (NULL, &whichItem);
GetDItem (maskDialog, whichItem, &itemType, &itemStuff, &itemRect);
switch (itemType)
{
case ctrlItem + btnCtrl : /* CANCEL or OKAY */
if (whichItem == OKAY_BUTTON_ITEM)
{
currMask = 0L;
for (item=FIRST_MASK, bitNum=0; item<=LAST_MASK; item++, bitNum++)
{
GetDItem (maskDialog, item, &itemType, &itemStuff, &itemRect);
checkBoxState = GetCtlValue ( (ControlHandle) itemStuff);
currMask |= (checkBoxState==0) ? 0L : (1L<<bitNum);
}
done = TRUE;
}
else if (whichItem == CANCEL_BUTTON_ITEM)
done = TRUE;
break;
case ctrlItem + chkCtrl : /* a category checkbox */
checkBoxState = GetCtlValue ( (ControlHandle) itemStuff);
if (checkBoxState == 0)
SetCtlValue ( (ControlHandle) itemStuff, 1);
else
SetCtlValue ( (ControlHandle) itemStuff, 0);
break;
default:
break;
}
}
/* On exit, trash dialog record and controls */
DisposDialog (maskDialog);
}
/** Trace() -- Checks current mask **/
void CTrace::Trace
(
unsigned long mask, /* severity of message */
char *format, /* format for user's arguments */
... /* arguments to format (varg) */
)
{
static char
traceBuff[MAX_LOGREC_CHAR], /* string that will be added to log */
userBuff[MAX_LOGREC_CHAR*2], /* user's contribution to log record */
prefix[40]; /* date+time string */
int
maxUserBuff; /* maximum length of formatted user string */
long
timeSecs; /* current time/date */
DateTimeRec
dateRec; /* time/date in MM/DD/YY HH:MM:SS components */
/* Should the message get added to the trace log? */
if ( (currMask & mask) != 0)
{
/* format the user's portion of the message */
vsprintf (userBuff, format, __va(format));
/* make sure the entire record will fit into traceBuff */
if (strlen (userBuff) > MAX_USER_BUFF)
userBuff[MAX_USER_BUFF] = NULL;
/* build log message and add it to the log */
GetDateTime (&timeSecs);
Secs2Date (timeSecs, &dateRec);
sprintf (traceBuff, "%02d/%02d/%02d--%02d:%02d:%02d %s",
dateRec.month, dateRec.day, dateRec.year-1900,
dateRec.hour, dateRec.minute, dateRec.second,
userBuff);
itsLogPanorama->AddString (traceBuff);
}
}
/** IsItVisible() -- Returns 'visible' flag to update menu bar entries. **/
Boolean CTrace::IsItVisible(void)
{
return (itsWindow->visible);
}
/** UpdateMenus() -- Disables Save and Revert entries **/
void CTrace::UpdateMenus(void)
{
inherited::UpdateMenus ();;
gBartender->DisableCmd (cmdSave);
gBartender->DisableCmd (cmdRevert);
}
/** DoSaveAs() -- Writes out contents of itsLogList to indicated file. **/
Boolean CTrace::DoSaveAs
(
SFReply *macSFReply /* the user's choice of file */
)
{
char logRecBuff[MAX_LOGREC_CHAR]; /* buffer for log entry */
short maxRec, /* number of records in LogList */
offsetToNull, /* byte offset to end of log entry */
rec; /* loop counter */
/* Dispose of the data used for the old file record */
if (itsFile != NULL)
itsFile->Dispose ();
/* Set up the new data file (no error checking!) */
itsFile = new (CDataFile);
((CDataFile *)itsFile)->IDataFile ();
itsFile->SFSpecify (macSFReply);
itsFile->CreateNew (gSignature, 'TEXT');
itsFile->Open (fsRdWrPerm);
/* Write out all records in list (add carriage return to end of each line).*/
maxRec = (short)(itsLogPanorama->itsLogList)->GetNumItems();
for (rec=1; rec<=maxRec; rec++)
{
(itsLogPanorama->itsLogList)->GetString (rec, logRecBuff);
offsetToNull = strlen (logRecBuff);
logRecBuff[offsetToNull] = '\r';
((CDataFile*)itsFile)->WriteSome (logRecBuff, offsetToNull+1);
}
return (TRUE);
}